package com.sky.utils;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.http.HttpException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.List;

@Slf4j
@Component
public class HttpUtil {

    @Resource
    @Qualifier("okHttpClientCommon")
    private OkHttpClient okHttpClient;

    @Autowired
    private Gson gson;

    private static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
    private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36";

    /**
     * GET请求 - 返回单个对象
     */
    public <T> T get(String url, Class<T> responseType) throws IOException {
        return execute(new Request.Builder().url(url).get().build(), responseType);
    }

    /**
     * GET请求 - 返回列表
     */
    public <T> List<T> getList(String url, Class<T> elementType) throws IOException {
        return executeList(new Request.Builder().url(url).get().build(), elementType);
    }

    /**
     * POST请求(对象参数) - 返回单个对象
     */
    public <T> T post(String url, Object requestBody, Class<T> responseType) throws IOException {
        return post(url, gson.toJson(requestBody), responseType);
    }

    /**
     * POST请求(对象参数) - 返回列表
     */
    public <T> List<T> postList(String url, Object requestBody, Class<T> elementType) throws IOException {
        return postList(url, gson.toJson(requestBody), elementType);
    }

    /**
     * POST请求(JSON字符串参数) - 返回单个对象
     */
    public <T> T post(String url, String jsonBody, Class<T> responseType) throws IOException {
        RequestBody body = RequestBody.create(jsonBody, JSON);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        return execute(request, responseType);
    }

    /**
     * POST请求(JSON字符串参数) - 返回列表
     */
    public <T> List<T> postList(String url, String jsonBody, Class<T> elementType) throws IOException {
        RequestBody body = RequestBody.create(jsonBody, JSON);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        return executeList(request, elementType);
    }

    /**
     * 执行HTTP请求 - 返回单个对象
     */
    private <T> T execute(Request request, Class<T> responseType) throws IOException {
        ApiResponse<T> response = executeRequest(request, responseType);
        return response.getData();
    }

    /**
     * 执行HTTP请求 - 返回列表
     */
    private <T> List<T> executeList(Request request, Class<T> elementType) throws IOException {
        ApiResponse<List<T>> response = executeRequest(request, TypeToken.getParameterized(List.class, elementType).getType());
        return response.getData();
    }

    /**
     * 通用请求执行逻辑
     */
    private <T> ApiResponse<T> executeRequest(Request request, Type responseType) throws IOException {
        Request enhancedRequest = enhanceRequest(request);

        try (Response response = okHttpClient.newCall(enhancedRequest).execute()) {
            log.info("response:{}", response);
            if (!response.isSuccessful()) {
                log.error("HTTP请求失败: url={}, code={}, message={}",
                        request.url(), response.code(), response.message());
                throw new HttpException("HTTP请求失败: " + response.code() + " " + response.message());
            }
            if (response.body() == null) {
                return null;
            }
            String responseBody = response.body().string();
            log.info("HTTP响应: url={}, response={}", request, responseBody);

            // 如果返回类型是String,直接返回
            if (responseType == String.class) {
                return (ApiResponse<T>) new ApiResponse<String>().setData(responseBody).setStatus("success");
            }

            // 解析通用响应结构
            ApiResponse<T> apiResponse = parseResponse(responseBody, responseType);
            log.info("apiResponse:{}", apiResponse);
            if (!apiResponse.isSuccess()) {
                if (apiResponse.getMessage() != null) {
                    throw new BusinessException(apiResponse.getMessage());
                } else {
                    throw new BusinessException("响应体解析失败");
                }
            }
            return apiResponse;
        } catch (Exception e) {
            log.error("HTTP请求异常: url={}, error={}", request.url(), e.getMessage(), e);
            throw e;
        }
    }

    /**
     * 增强请求(添加通用Header等)
     */
    private Request enhanceRequest(Request original) {
        return original.newBuilder()
                .header("User-Agent", USER_AGENT)
                .header("Accept", "application/json")
                .build();
    }

    /**
     * 解析API响应
     */
    private <T> ApiResponse<T> parseResponse(String responseBody, Type responseType) {
        // 构造包含泛型的完整类型
        Type fullType = TypeToken.getParameterized(ApiResponse.class, responseType).getType();
        return gson.fromJson(responseBody, fullType);
    }

    /**
     * HTTP请求异常
     */
    public static class HttpException extends RuntimeException {
        public HttpException(String message) {
            super(message);
        }
    }

    /**
     * 业务异常
     */
    public static class BusinessException extends RuntimeException {
        public BusinessException(String message) {
            super(message);
        }
    }

    /**
     * API统一响应结构
     */
    @Data
    @Accessors(chain = true)
    public static class ApiResponse<T> {
        private String status;
        private String message;
        private T data;

        public boolean isSuccess() {
            return status.equals("success");
        }
    }
}